package main

import "fmt"

// for-range语法,用于遍历array、slice和map
func main() {
	//forRangeCollection()

	//forRangeMap()

	doNotUseTraverseVariable()
}

// 通过for遍历集合
func forRangeCollection() {
	s := []int{1, 2, 3, 4, 5}
	for i, v := range s {
		fmt.Printf("index: %d\tvalue: %d\n", i, v)
	}

	//使用完整的for-range遍历
	println("使用完整的for-range遍历")

	//遍历时忽略下标,仅遍历值
	println("遍历时忽略下标,仅遍历值")
	for _, v := range s {
		fmt.Printf("value:%d\n", v)
	}

	//遍历时忽略值,通过下标访问
	println("遍历时忽略值,通过下标访问")
	for i := range s {
		fmt.Printf("index: %d\tvalue: %d\n", i, s[i])
	}

}

func forRangeMap() {
	m := map[string]string{
		"k1": "v1",
		"k2": "v2",
		"k3": "v3",
	}

	//使用完整的for-range遍历
	println("使用完整的for-range遍历")
	for k, v := range m {
		fmt.Printf("key: %s\tvalue: %s\n", k, v)
	}

	//遍历时忽略key,仅遍历value
	println("遍历时忽略key,仅遍历value")
	for _, v := range m {
		fmt.Printf("value: %s\n", v)
	}

	//遍历时忽略value,通过key访问
	println("遍历时忽略value,通过key访问")
	for k := range m {
		fmt.Printf("key: %s\tvalue: %s\n", k, m[k])
	}
}

// 不要直接使用遍历时的迭代参数
func doNotUseTraverseVariable() {
	//不要直接使用遍历时的迭代参数
	//因为迭代参数就是一个内存地址,这个地址在遍历开始时就确定了,直接使用的话,会导致最终每个变量都是相同的值

	users := []user{
		{name: "Tom"},
		{name: "Jerry"},
	}

	userMap := make(map[string]*user, len(users))

	for _, u := range users { //这里变量u的内存地址在遍历开始时就确定了,会导致最终map里所有的user都是同一个
		userMap[u.name] = &u
	}

	for k, v := range userMap {
		fmt.Printf("name: %s\t, user: %v\n", k, v)
	}
}

type user struct {
	name string
}
